module dogre.vector3;

extern(C)
{
    void* getVector3();
    void* getVector3FromCoordinates(float, float, float);
    float* call_Vector3ptr(void* ptr);
    float* get_Vector3ptrX(void* ptr);
    float* get_Vector3ptrY(void* ptr);
    float* get_Vector3ptrZ(void* ptr);
}

class Vector3  //Trying something new here.
{
    void* p;
    float* px, py, pz;
    this()
    {
        p = getVector3();
        _getptrs();
    }
    this(void* ptr)
    {
        assert(ptr);
        p = ptr;
        _getptrs();
    }
    private void _getptrs()
    {
        px = call_Vector3ptr(p);
        py = get_Vector3ptrY(p);
        pz = get_Vector3ptrZ(p);
    }
    this(float xval, float yval, float zval)
    {
        p = getVector3FromCoordinates(xval, yval, zval);
        _getptrs();
    }
    
	~this(){}
	
    invariant()
    {
        assert(px == call_Vector3ptr(p));
        assert(py == get_Vector3ptrY(p));
        assert(pz == get_Vector3ptrZ(p));
    }
    float* ptr()
    {
        return px;
    }
    @property float x()
    {
        return *px;
    }
    @property void x(float value)
    {
        *px = value;
    }
    @property float y()
    {
        return *py;
    }
    @property void y(float value)
    {
        *py = value;
    }
    @property float z()
    {
        return *pz;
    }
    @property void z(float value)
    {
        *pz = value;
    }
	
	static Vector3 ZERO()
	{
		return new Vector3(0,0,0);
	}
    
    static Vector3 UNIT_Y()
    {
        return new Vector3(0,1,0);
    }
    
    static Vector3 UNIT_X()
    {
        return new Vector3(1,0,0);
    }
    
    static Vector3 UNIT_Z()
    {
        return new Vector3(0,0,1);
    }
    
    static Vector3 UNIT_SCALE()
    {
        return new Vector3(1,1,1);
    }
}
